﻿using System;
using System.Diagnostics;
using System.Text;
using Glue;
using Glue.Internals.PrintTool;
using Xunit;

namespace GlueExamples.CompleteExamples
{

    public class FlatteningLargeStructure
    {
        private readonly Mapping<Event, EventInfo> theMapping;

        public FlatteningLargeStructure()
        {
            theMapping = new Mapping<Event, EventInfo>();
            // EventName, Location, Start, End, EntryDescription, OrganizerOrgName, ActivityName, EntryContactPersonName, EntryContactPhone, EntryContactEmail, EntryContactHomePage, Level, SeasonName, OrganizerContactPhone, OrganizerContactEmail, OrganizerContactHomePage, ArrangingOrganizaionId, ActivityId, ParentActivityId, DeadLine,
            theMapping.Relate(x=>x.Activity.Id , y=>y.ActivityId);
            theMapping.Relate(x => x.Activity.Name, y => y.ActivityName);
            theMapping.Relate(x => x.Activity.ParentActivityId, y => y.ParentActivityId);
            theMapping.Relate(x => x.ArrangingOrganization.OrgId, y => y.ArrangingOrganizaionId);
            theMapping.Relate(x => x.End, y => y.End);
            theMapping.Relate(x => x.EntryInfo.Contact.Email, y => y.EntryContactEmail);
            theMapping.Relate(x => x.EntryInfo.Contact.HomePage, y => y.EntryContactHomePage);
            theMapping.Relate(x => x.EntryInfo.Contact.TelephoneNo1, y => y.EntryContactPhone);
            theMapping.Relate(x => x.EntryInfo.ContactPersonName, y => y.EntryContactPersonName);
            theMapping.Relate(x => x.EntryInfo.Description, y => y.EntryDescription);
            theMapping.Relate(x => x.EventName, y => y.EventName);
            theMapping.Relate(x => x.GetLastDeadLine().Date, y => y.DeadLine);
            theMapping.Relate(x => x.Level, y => y.Level);
            theMapping.Relate(x => x.Location, y => y.Location);
            theMapping.Relate(x => x.Organizer.Contact.Email, y => y.OrganizerContactEmail);
            theMapping.Relate(x => x.Organizer.Contact.HomePage, y => y.OrganizerContactHomePage);
            theMapping.Relate(x => x.Organizer.Contact.TelephoneNo1, y => y.OrganizerContactPhone);
            theMapping.Relate(x => x.Organizer.OrgName, y => y.OrganizerOrgName);
            theMapping.Relate(x => x.Season.Name, y => y.SeasonName);
            theMapping.Relate(x => x.Start, y => y.Start);
        }

        [Fact]
        public void AssertAllPropertiesMapped()
        {
            theMapping.GetRelationsVerification().AssertAllPropertiesRelated<EventInfo>();
        }

        [Fact]
        public void TestMapping()
        {
            theMapping.GetMapperVerification().AssertMapsCorrectlyTowards(new EventInfo());
        }

        [Fact]
        public void Print()
        {
            PrintWithPrintTool(theMapping, x => Debug.WriteLine(x));
        }

        [Fact]
        public void Should_equal_setup_with_mappers()
        {
            var mappersMapping = FlatteingLargeStructureUsingMappers.GetMapper();
            var mappersMappingReportBuilder = new StringBuilder();
            PrintWithPrintTool(mappersMapping, x => mappersMappingReportBuilder.Append(x));

            var thisMappingReportBuilder = new StringBuilder();
            PrintWithPrintTool(mappersMapping, x => thisMappingReportBuilder.Append(x));
            Assert.Equal(mappersMappingReportBuilder.ToString(),thisMappingReportBuilder.ToString());
        }

        private void PrintWithPrintTool(Mapping<Event, EventInfo> mapping, Action<string> output)
        {
            var printTool = new PrintTool<Event, EventInfo>(mapping);
            var report = printTool.GetReport();
            report.SortOnLeftColumn();
            printTool.Print(report, output);

        }
    }
}
